﻿//Socket.cpp
#include "Socket.h"

int CSocket::ms_SocketCount=0;

CSocket::CSocket()
{
	if (ms_SocketCount==0)
	{
		WSADATA wsa;
		//初始化套接字DLL
		if (WSAStartup(MAKEWORD(2,2),&wsa)!=0)
		{
			cout << ("WSAStartup()") << endl << "出错代码：" << WSAGetLastError() << endl << "出错文件：" << __FILE__ << endl << "出错行数：" << __LINE__ << endl;
			exit(-1);
		}
		
	}
	ms_SocketCount++;
	m_hSock = NULL;

	m_hSock=socket(AF_INET,SOCK_STREAM,0);
	if (m_hSock==INVALID_SOCKET)
	{
		m_hSock=NULL;
	}

}

CSocket::CSocket(SOCKET sock)
{
	ms_SocketCount++;
	m_hSock=sock;
}

CSocket::~CSocket()
{
	ms_SocketCount--;
	if (ms_SocketCount==0)
	{
		WSACleanup();
	}
	m_hSock=NULL;
}

void CSocket::Close()
{
	if (m_hSock)
	{
		closesocket(m_hSock);
		m_hSock=NULL;
	}

}

bool CSocket::Connect(const char* ip,short port)
{
	if (!m_hSock)
	{
		return false;
	}
	struct sockaddr_in serverAddress;
	memset(&serverAddress,0,sizeof(sockaddr_in));
	serverAddress.sin_family=AF_INET;
	serverAddress.sin_addr.S_un.S_addr = inet_addr(ip);
	serverAddress.sin_port=htons(port);

	//建立和服务器的连接
	if (connect(m_hSock,(sockaddr*)&serverAddress,sizeof(serverAddress))==SOCKET_ERROR)
	{
		closesocket(m_hSock);
		m_hSock=NULL;
		return false;
	}
	return true;

}

bool CSocket::SetRecvTimeout(int timeout /*=5000*/)
{
	if (SOCKET_ERROR==setsockopt(m_hSock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)))
	{
		return false;
	}
	return true;
}

bool CSocket::Listen(const char* ip,short port)
{
	SOCKADDR_IN addr;
	memset(&addr,0,sizeof(SOCKADDR_IN));
	addr.sin_family=AF_INET;
	addr.sin_addr.s_addr = inet_addr(ip);
	addr.sin_port=htons(port);
	int ret =bind(m_hSock,(SOCKADDR*)&addr,sizeof(SOCKADDR));

	if (SOCKET_ERROR==ret)
	{
		cout << ("bind()") << endl << "出错代码：" << WSAGetLastError() << endl << "出错文件：" << __FILE__ << endl << "出错行数：" << __LINE__ << endl;
		closesocket(m_hSock);
		m_hSock=NULL;
		return false;
	}

	ret = listen(m_hSock,30);
	if (SOCKET_ERROR==ret)
	{
		cout << ("listen()") << endl << "出错代码：" << WSAGetLastError() << endl << "出错文件：" << __FILE__ << endl << "出错行数：" << __LINE__ << endl;
		closesocket(m_hSock);
		m_hSock=NULL;
		return false;
	}
	cout << "Listening..." << endl;

	return true;
}

string CSocket::getClientIP()
{
	SOCKADDR addr={0};
	int len = sizeof(SOCKADDR);
	getpeername(m_hSock,&addr,&len);

	char peer[128];
	unsigned char* paddr = (unsigned char*)&addr;
	sprintf_s(peer,128,"%d.%d.%d.%d",paddr[4],paddr[5],paddr[6],paddr[7]);
	return string(peer);
}

CSocket* CSocket::Accept(int timeout /*=5*/)
{
	struct sockaddr_in client={0};
	int addrlen;
	addrlen=sizeof(client);
	SOCKET sock = accept(m_hSock,(sockaddr*)&client,&addrlen);

	int err = WSAGetLastError();
	if (sock == INVALID_SOCKET)
	{
		return NULL;
	}

	return new CSocket(sock);
}

string CSocket::getHostIP(const char* host)
{
	struct hostent *host_entry;
	host_entry = gethostbyname(host);

	if (host_entry)
	{
		char * szLocalIP;
		szLocalIP = inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
		return string(szLocalIP);
	} 
	return "";
}

void LogToFile(const char* pData, int len)
{
	static CRITICAL_SECTION Critical = {0};
	if (Critical.OwningThread == 0)
	{
		InitializeCriticalSection((LPCRITICAL_SECTION)&Critical);
	} 
	EnterCriticalSection(&Critical);
	FILE* fp = NULL;
	int ret = fopen_s(&fp, "socket.txt", "ab");
	if (ret)
	{
		return;
	}

	fwrite(pData, len, 1, fp);
	const char* pSp = "\r\n--------------------------------------------------\r\n";
	fwrite(pSp, (int)strlen(pSp), 1, fp);
	fclose(fp);
	LeaveCriticalSection(&Critical);
}

int CSocket::Send(const char* pData, int len)
{
	int nByteSend = 0;
	nByteSend = send(m_hSock, pData, len, 0);
	LogToFile(pData, nByteSend);
	return nByteSend;
}

int CSocket::Recv(char* pData, int len)
{
	int nByteRecv = 0;
	nByteRecv = recv(m_hSock, pData, len, 0);
	LogToFile(pData, nByteRecv);
	return nByteRecv;
}